﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using YXH_Tools_Files.ObjectClass;
using YXH_Tools_Files.Tools_Error;

namespace YXH_Tools_Files.Tools_Spike
{
    public static class Spike_Removal
    {
        /// <summary>
        /// 先每meanblocklength个点算均值
        /// </summary>
        /// <param name="list">数据源</param>
        /// <param name="meanblocklength">均值点数</param>
        /// <returns></returns>
        public static List<double> meanSignalCal(List<double> list,int meanblocklength)
        {
            List<double> M = new List<double>();
            for (int i = 0; i < list.Count; i++)
            {
                var half = meanblocklength / 2;
                double t = 0;
                int lessthan = 0;
                for (int j = i-half; j <= i+half; j++)
                {
                    
                    if ((j) < 0)
                    {
                        //t += list[0];
                        t += 0;
                        lessthan++;
                    }
                    else
                    {
                        if (j >= list.Count)
                        {
                            //t += list[list.Count - 1];
                            t += 0;
                            lessthan++;
                        }
                        else
                        {
                            t += list[j];
                        }
                    }
                   
                }
                M.Add(t / (meanblocklength- lessthan));
            }
            return M;
        }

        /// <summary>
        /// 创建一个新的rough数据（原数据-均值数据）
        /// </summary>
        /// <param name="orignal">原数据</param>
        /// <param name="smooth">均值数据</param>
        /// <returns></returns>
        public static List<double> createRoughSignal(List<double> orignal, List<double> smooth)
        {
            List<double> newlist = new List<double>();
            for (int i = 0; i < orignal.Count; i++)
            {
                newlist.Add(orignal[i] - smooth[i]);
            }
            return newlist;
        }
        /// <summary>
        /// 计算MRi的值
        /// </summary>
        /// <param name="rough">rough数据</param>
        /// <param name="varianceblocklength">方差点数</param>
        /// <returns></returns>
        public static List<double> MRiCal(List<double> rough, int varianceblocklength)
        {
            List<double> MR = new List<double>();
            for (int i = 0; i < rough.Count; i++)
            {
                var half = varianceblocklength / 2;
                double t = 0;
                int lessthan = 0;
                for (int j = i - half; j <= i + half; j++)
                {
                    if ((j) < 0)
                    {
                        //t += rough[0];
                        t += 0;
                        lessthan++;
                    }
                    else
                    {
                        if (j >= rough.Count)
                        {
                            //t += rough[rough.Count - 1];
                            t += 0;
                            lessthan++;
                        }
                        else
                        {
                            t += rough[j];
                        }
                    }

                }
                MR.Add(t / (varianceblocklength - lessthan));
            }
            return MR;
        }
        /// <summary>
        /// 计算方差信号
        /// </summary>
        /// <param name="R">rough数据</param>
        /// <param name="MR">MR数据</param>
        /// <param name="varianceblocklength">方差点数</param>
        /// <returns></returns>
        public static List<double> varianceSignalCal(List<double> R, List<double> MR, int varianceblocklength)
        {
            List<double> V = new List<double>();
            for (int i = 0; i < R.Count; i++)
            {
                var half = varianceblocklength / 2;
                double t = 0;
                int lessthan = 0;
                for (int j = i - half; j <= i + half; j++)
                {
                   
                    if ((j) < 0)
                    {
                        //t += Math.Pow((R[0] - MR[0]), 2);
                        t += 0;
                        lessthan++;
                    }
                    else
                    {
                        if (j >= R.Count)
                        {
                            //t += Math.Pow((R[R.Count - 1] - MR[MR.Count - 1]), 2);
                            t += 0;
                            lessthan++;
                        }
                        else
                        {
                            t += Math.Pow(R[j] - MR[j],2);
                        }
                    }

                }
                V.Add(t /( varianceblocklength-1 - lessthan));
            }
            return V;
        }

        /// <summary>
        /// 最大最小标准归一化
        /// </summary>
        /// <param name="variance"></param>
        /// <returns></returns>
        public static List<double> MinMaxNormalization(this List<double> variance)
        {

            double dataMax = variance.Max();
            double dataMin = variance.Min();
            List<double> V = new List<double>();
            foreach (var item in variance)
            {
                var d = (item - dataMin) / (dataMax - dataMin);
                V.Add(d);
            }
            return V;
        }


        /// <summary>
        /// 检测spike点，大于最大方差百分比的即为spike
        /// </summary>
        /// <param name="variance"></param>
        /// <param name="percentage">最大方差的百分比</param>
        /// <returns></returns>
        public static List<int> detectSpikes(List<double> variance,double percentage)
        {
           var threshold= variance.Max()*percentage;
            List<int> spikesindex = new List<int>();
            for (int i = 0; i < variance.Count; i++)
            {
                if (variance[i] > threshold)
                {
                    spikesindex.Add(i);
                }
            }
            return spikesindex; 
        }
        /// <summary>
        /// 检测spike点，大于threshold即为spike
        /// </summary>
        /// <param name="variance"></param>
        /// <param name="percentage">最大方差的百分比</param>
        /// <returns></returns>
        public static List<int> detectSpikesV2(List<double> variance, double threshold)
        {
            List<int> spikesindex = new List<int>();
            for (int i = 0; i < variance.Count; i++)
            {
                if (variance[i] > threshold)
                {
                    spikesindex.Add(i);
                    //Console.WriteLine($"{i},{variance[i]}");
                }
            }
            return spikesindex;
        }
        /// <summary>
        /// 线性插值
        /// </summary>
        /// <param name="value1">插值起始点</param>
        /// <param name="value2">插值终止点</param>
        /// <param name="numberOfInterpolations">插值数量</param>
        /// <returns></returns>
        public static double[] linearInterpolation(double value1, double value2, int numberOfInterpolations)
        {
            double[] interpolations = new double[numberOfInterpolations ];
            double step = (value2 - value1) / (numberOfInterpolations + 1);

            //interpolations[0] = value1;
            //interpolations[numberOfInterpolations + 1] = value2;

            for (int i = 0; i < numberOfInterpolations; i++)
            {
                interpolations[i] = value1 + (step * i);
            }

            return interpolations;
        }
        /// <summary>
        /// 将输入的List<int>数据分组合并输出
        /// </summary>
        /// <param name="numbers"></param>
        /// <returns></returns>
        public static List<List<int>> GroupConsecutiveNumbers(List<int> numbers)
        {
            List<List<int>> result = new List<List<int>>();

            if (numbers.Count == 0)
            {
                return result;
            }
            //创建了一个名为currentGroup的List<int>类型变量，并将其中的第一个元素设置为numbers列表中的第一个元素。
            List<int> currentGroup = new List<int>() { numbers[0] };
            //这部分代码使用循环遍历numbers列表中的元素。在每次循环中，它检查当前元素是否与前一个元素相差1，
            //如果是，则将当前元素添加到currentGroup中。如果不是，则说明当前元素与前一个元素不连续，
            //需要将currentGroup添加到结果列表result中，并重新创建一个新的currentGroup来存储下一个连续的数字。
            for (int i = 1; i < numbers.Count; i++)
            {
                if (Math.Abs(numbers[i] - numbers[i - 1] )<=4)
                {
                    currentGroup.Add(numbers[i]);
                    
                }
                else
                {
                    result.Add(currentGroup);
                    currentGroup = new List<int>() { numbers[i] };
                }
            }

            result.Add(currentGroup);

            return result;
        }
        /// <summary>
        /// 把合并好的每组的不连续的数字改为连续的数字
        /// </summary>
        /// <param name="groups"></param>
        public static List<List<int>> MergeConsecutiveGroups(List<List<int>> groups)
        {
            foreach (var g in groups)
            {
                for (int i = 0; i < g.Count; i++)
                {
                    if (g[g.Count - 1] - g[0] + 1 != g.Count)
                    {
                       var cv= Enumerable.Range(g[0], g[g.Count - 1] - g[0] + 1).ToArray();
                        g.Clear();
                        g.AddRange(cv);
                    }
                }
            }
            return groups;
            
        }

        /// <summary>
        /// 把合并好的每组的数量小于20的添加到20个，因为小于20的话可能spike删的不够彻底
        /// </summary>
        /// <param name="groups"></param>
        /// /// <param name="signalcount">原信号数量</param>
        /// <returns></returns>
        public static List<List<int>> AddPointsConsecutiveGroups(List<List<int>> groups,int signalcount)
        {
            List < List<int> > newgroups=new List<List<int>>();
            foreach (var item in groups)
            {
                if (item.Count < 40)
                {
                    var first = item.First();
                    var last = item.Last();
                    List<int> forehead=new List<int>();
                    //List<int> lasthead = new List<int>();
                    //判断第一个数是否大于10，如果是，则说明往前添加10个数没有问题
                    if (first - 20 >= 0)
                    {
                        forehead= Enumerable.Range(first - 20, 20).ToList();
                        forehead.AddRange(item);
                      
                        //然后再判断最后一个数是否小于2550，如果小，说明足够在后面也添加10个数
                        if (signalcount - last > 20)
                        {
                            var lasthead = Enumerable.Range(last + 1, 20).ToList();
                            forehead.AddRange(lasthead);

                        }
                        //如果不是，则一直添加到信号中最后一个index，不管数量了
                        else
                        {
                            //判断是不是最后一个数
                            if (last != signalcount - 1)
                            {
                                var lasthead = Enumerable.Range(last + 1, signalcount - last - 1).ToList();
                                forehead.AddRange(lasthead);
                            }
                          
                        }
                        
                    }
                    else
                    {
                        //不管前面数量了，从0开始能添加几个就添加几个，后面肯定能添加10个以上
                        forehead= Enumerable.Range(0, first).ToList();
                        forehead.AddRange(item);
                        var lasthead = Enumerable.Range(last + 1, 20).ToList();
                        forehead.AddRange(lasthead);
                   
                    }
                    newgroups.Add(forehead);

                }
                else
                {
                    newgroups.Add(item);
                }
            }
            return newgroups;
        }

        /// <summary>
        /// 根据分组连续的数字来进行插值
        /// </summary>
        /// <param name="original"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static List<List<double>> getInterceptvalue(List<double> original, List<List<int>> index)
        {
            List<List<double>> nospike =new List<List<double>>();
            for (int i = 0; i < index.Count; i++)
            {
                var interceptcount = index[i].Count;//插值的数量
                //不考虑原数据第一个数或者最后一个数为spike的情况
                if (index[i][0]> 0 && index[i][index[i].Count - 1]+1< original.Count)
                {
                    List<double> list=new List<double>();
                    var firstdata = original[index[i][0] - 1];//拿到插值的起点数
                    var lastdata = original[index[i][index[i].Count - 1] + 1];//拿到插值的终点数
                    
                    var newdata=linearInterpolation(firstdata,lastdata, interceptcount);
                    foreach (var item in newdata)
                    {
                        list.Add(item);
                    }
                    nospike.Add(list);
                }
                else
                {
                    //如果是第一个或者最后一个为spike则原始数据不动
                    List<double> list = new List<double>();
                    for (int j = 0; j < interceptcount; j++)
                    {
                        list.Add(original[j]);
                    }
                    nospike.Add(list);
                }
            }
            return nospike;
        }


        public static List<List<double>> getMedianFilterValue(List<double> original, List<List<int>> index)
        {
            List<List<double>> nospike = new List<List<double>>();
            for (int i = 0; i < index.Count; i++)
            {
                var interceptcount = index[i].Count;//插值的数量
                List<double> list = new List<double>();
                //把每组的index里序号对应原始数据的值放到list里来，保证超过4个以上
                for (int j = 0; j < interceptcount; j++)
                {
                    list.Add(original[index[i][j]]);
                    if (interceptcount < 2)
                    {
                        //如果数量为1，则添加前一个数或者后一个数，也就是说最少也要2个数
                        list.Add(index[i][j] - 1 < 0 ? original[index[i][j]+1]: original[index[i][j] -1]);
                    }
                }
                //中值滤波
               var nd= Filter.MedianFilter(list.ToArray(), list.Count>5? list.Count/2: list.Count-1).ToList();
                //如果数量不相等，说明index里面只有1个值，所以要在滤波后的数组中删除后一个数，以保证nd的数量和index的数量一致
                if(nd.Count != interceptcount)
                {
                  nd.RemoveAt(nd.Count - 1);
                }
                nospike.Add(nd);
            }
            return nospike;
        }

        public static List<List<double>> getRCLowPassFilterValue(List<double> original, List<List<int>> index)
        {
            List<List<double>> nospike = new List<List<double>>();
            for (int i = 0; i < index.Count; i++)
            {
                var interceptcount = index[i].Count;//插值的数量
                List<double> list = new List<double>();
                //把每组的index里序号对应原始数据的值放到list里来，保证超过4个以上
                for (int j = 0; j < interceptcount; j++)
                {
                    list.Add(original[index[i][j]]);
                   
                }
               
                var nd = Filter.RCLowPass(list.ToArray(),5,512).ToList();
              
                nospike.Add(nd);
            }
            return nospike;
        }
        /// <summary>
        /// 按比例缩小到均值处理，输出的只是spike处理过后的数据，并不是全部的数据
        /// </summary>
        /// <param name="original"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static List<List<double>> getratioFilterValue(List<double> original, List<List<int>> index,double ratio)
        {
            List<List<double>> nospike = new List<List<double>>();
            var mean=original.Average();
            for (int i = 0; i < index.Count; i++)
            {
                var interceptcount = index[i].Count;//插值的数量
                List<double> list = new List<double>();
                //把每组的index里序号对应原始数据的值放到list里来
                for (int j = 0; j < interceptcount; j++)
                {
                    list.Add(original[index[i][j]]);
                }
                var nd = Filter.RatioPass(list.ToArray(), mean, ratio).ToList();

                nospike.Add(nd);
            }
            return nospike;
        }

        /// <summary>
        /// 源数据根据spike的index改为插值,输出的是去除spike后的源数据,是全部数据
        /// </summary>
        /// <param name="original"></param>
        /// <param name="interceptvalue"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public static List<double> removeSpike( List<double> original, List<List<double>> interceptvalue, List<List<int>> index)
        {
            for (int i = 0; i < index.Count; i++)
            {
                for (int j = 0; j < index[i].Count; j++)
                {
                 
                    original[index[i][j]] = interceptvalue[i][j];
                }

            }
            return original;
        }

        public static List<List<int>> getAccurateSpikeIndex(List<double> original, List<List<int>> index)
        {
            List<List<int>> resultindex = new List<List<int>>();
            try
            {
                if (index.Count > 0)
                {

                    //先计算信号的均值
                    var avg = original.Average();

                    for (int i = 0; i < index.Count; i++)
                    {
                        //创建一个list存储spike周围的值
                        List<double> list = new List<double>();
                        foreach (var value in index[i])
                        {
                            list.Add(original[value]);
                        }
                        //获取|最大值-avg|的list里面的index
                        var maxindex = Math.Abs(list.Min() - avg) > Math.Abs(list.Max() - avg) ? list.IndexOf(list.Min()) : list.IndexOf(list.Max());
                        //获取原始信号里的最大值的index
                        var maxidxinsignal = index[i][maxindex];
                        //获取最大值与均值的差
                        var maxvalue = Math.Abs(list[maxindex] - avg) * 0.9;
                        if (maxidxinsignal > 1 && maxidxinsignal < original.Count - 2)
                        {
                            var v1 = Math.Abs(original[maxidxinsignal] - original[maxidxinsignal - 2]);//spike点与第前三个点的差值
                            var v2 = Math.Abs(original[maxidxinsignal] - original[maxidxinsignal + 2]);//spike点与第后三个点的差值
                            if (v1 > v2)
                            {
                                if (maxidxinsignal > 2)
                                {
                                    
                                    var v3 = Math.Abs(original[maxidxinsignal] - original[maxidxinsignal -3])*0.9;//spike点与第前四个点的差值*0.9
                                    //如果spike点与前一个点的差值大于spike点与第前两个点的差值90%以上
                                    if (v1 > (maxvalue > v3 ? maxvalue : v3))//判断spike点与第前两个点的差值90%和spike点与均值的差值90%，哪个大就用哪个
                                    {
                                        resultindex.Add(index[i]);
                                    }
                                }
                                else//maxidxinsignal只能等于2，说明是第四个点，那就判断如果spike点与第前3个点的差值是否大于最大值与均值的差的90%
                                {
                                   if(v1 > maxvalue)
                                    {
                                        resultindex.Add(index[i]);
                                    }
                                }
                            }
                            else
                            {
                                if(maxidxinsignal< original.Count - 3)
                                {
                                    var v3 = Math.Abs(original[maxidxinsignal] - original[maxidxinsignal + 3]) * 0.9;//spike点与第后两个点的差值*0.9
                                    if (v2 > (maxvalue > v3 ? maxvalue : v3))//如果spike点与后一个点的差值大于spike点与第后两个点的差值90%以上
                                    {
                                        resultindex.Add(index[i]);
                                    }
                                }
                                else//maxidxinsignal只能等于最后第三个点，那就判断如果spike点与后两个点的差值是否大于最大值与均值的差的90%
                                {
                                    if (v2 > maxvalue)
                                    {
                                        resultindex.Add(index[i]);
                                    }
                                }
                            }
                            
                            //if ((v1 > maxvalue) || (v2 > maxvalue))
                            //{
                            //    resultindex.Add(index[i]);
                            //}

                        }
                    }

                }
            }
            catch (Exception ex)
            {
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                LogErrorMessage.getErrormessage(methodName + "方法出现了错误：" + ex.Message);
                Console.WriteLine(methodName + "方法出现了错误：" + ex.Message);
            }
           

            return resultindex;
        }


        /// <summary>
        /// 获取精确的spikeindex
        /// </summary>
        /// <param name="original"></param>
        /// <param name="index"></param>
      
        /// <returns></returns>
        public static List<List<int>> getAccurateSpikeIndexV2(List<double> original, List<List<int>> index)
        {
            List<List<int>> resultindex = new List<List<int>>();
            //double avgpeak=0;
            try
            {
                if (index.Count > 0)
                {
                    //先计算信号的均值
                    var avg = original.Average();
                    for (int i = 0; i < index.Count; i++)
                    {
                        //创建一个list存储spike周围的值
                        List<double> list = new List<double>();
                        //连续的点数不超过60个才能算spike
                        if (index[i].Count < 60)
                        {
                            foreach (var value in index[i])
                            {
                                list.Add(original[value]);
                            }
                            //获取|最大值-avg|的list里面的index
                            var maxindex = Math.Abs(list.Min() - avg) > Math.Abs(list.Max() - avg) ? list.IndexOf(list.Min()) : list.IndexOf(list.Max());
                            //获取原始信号里的最大值的index
                            var maxidxinsignal = index[i][maxindex];
                            //获取最大值与均值的差
                            var maxvalue = Math.Abs(list[maxindex] - avg);
                            var change = maxidxinsignal;
                            var changeadd = maxidxinsignal;
                           

                            ////这里选取最大值的之前15秒或者之后15秒数据
                            //if (maxidxinsignal > 7680)
                            //{
                            //    var before15sdata=original.GetRange(maxidxinsignal - 7680, 5120);
                            //    avgpeak=before15sdata.CalRangeAvg(10);
                            //}
                            //else if(maxidxinsignal +7680 < original.Count)
                            //{
                            //    var after15sdata = original.GetRange(maxidxinsignal +2560, 5120);
                            //    avgpeak = after15sdata.CalRangeAvg(10);
                            //}
                            //else
                            //{
                            //    avgpeak = original.CalRangeAvg(10);
                            //}
                            int turn1 = -1, turn2 = -1;//转折点
                            int turn3 = -1, turn4 = -1;//转折点
                            bool t = true;//指示是否第一次转折
                            bool t2 = true;//指示是否第一次转折
                            double secondLargest = 0;
                            //获得极值附件20个点的数据
                            if (maxidxinsignal > 19 && maxidxinsignal< original.Count-19)
                            {
                                var nearbydata = original.GetRange(maxidxinsignal - 20, 40);
                                //Console.WriteLine(original[maxidxinsignal]);
                                var vp = original[maxidxinsignal] - original[maxidxinsignal - 1];//最大点与前一个点的差值
                                if (vp > 0)
                                {
                                    //说明是峰值
                                    //获取这20个点的峰值
                                    var peak = nearbydata.Findpeaks(-2);
                                    if (peak.Count > 1)
                                    {
                                        secondLargest = peak.OrderByDescending(x => x).Skip(1).First();
                                    }
                                }
                                else
                                {
                                    var valley = nearbydata.Findpeaks(2);
                                    if (valley.Count > 1)
                                    {
                                        secondLargest = valley.OrderBy(x => x).Skip(1).First();
                                    }
                                }

                                //获得极值前面的转折点
                                while (change > 1)
                                {
                                    var v1 = original[change] - original[change - 1];//最大点与前一个点的差值
                                  
                                    var v2 = original[change - 1] - original[change - 2];//前一个点与前2个点的差值
                                    if (v1 * v2 < 0)//说明有转折
                                    {
                                        if (t)//第一次转折
                                        {
                                            turn1 = change - 1;//记录第一次转折点
                                            t = false;//后面不会再进来判断
                                        }
                                        else
                                        {
                                            turn2 = change - 1;//记录第二次转折点并跳出循环
                                            break;
                                        }
                                    }
                                    change--;
                                }
                                //获得极值后面的转折点
                                while (changeadd < original.Count - 1)
                                {
                                    var v1 = original[changeadd] - original[changeadd + 1];//最大点与前一个点的差值
                                    var v2 = original[changeadd + 1] - original[changeadd + 2];//前一个点与前2个点的差值
                                    if (v1 * v2 < 0)//说明有转折
                                    {
                                        if (t2)//第一次转折
                                        {
                                            turn3 = changeadd + 1;//记录第一次转折点
                                            t2 = false;//后面不会再进来判断
                                        }
                                        else
                                        {
                                            turn4 = changeadd + 1;//记录第二次转折点并跳出循环
                                            break;
                                        }

                                    }
                                    changeadd++;
                                }

                                if (turn1 != -1 && turn2 != -1 && turn3 != -1 && turn4 != -1 && secondLargest!=0)
                                {
                                    var s1 = Math.Abs(original[maxidxinsignal] - original[turn1]);
                                    var s2 = Math.Abs(secondLargest - original[turn1]);
                                    var s3 = Math.Abs(original[maxidxinsignal] - original[turn3]);
                                    var s4 = Math.Abs(secondLargest - original[turn3]);
                                    if ((turn3 - turn1) < 7 && (s1 / s2) > 3.5 && (s3 / s4) > 3.5)
                                    {
                                        resultindex.Add(index[i]);
                                        //如果spike识别出来的序号太多的话，最好只修改最大值附近的5个
                                        //if (index[i].Count > 10)
                                        //{
                                        //    if (maxindex > 1 && maxindex< index[i].Count-2)
                                        //    {
                                        //        resultindex.Add(index[i].GetRange(maxindex - 2, 5));
                                        //    }
                                        //    else if (maxindex<=1)
                                        //    {
                                        //        resultindex.Add(index[i].GetRange(0, 5));
                                        //    }
                                        //    else
                                        //    {
                                        //        resultindex.Add(index[i].GetRange(maxindex - 4, 5));
                                        //    }
                                        //}
                                        //else
                                        //{
                                        //    resultindex.Add(index[i]);
                                        //}

                                    }

                                    //看第二个转折点与第一个转折点的差值大还是第二个转折点和均值的差值大，哪个大取哪个
                                    //var s2 = Math.Abs(original[turn2] - original[turn1]) > Math.Abs(original[turn2] - avg) ? Math.Abs(original[turn2] - original[turn1]) : Math.Abs(original[turn2] - avg);
                                    //var s3 = s2 > avgpeak ? s2 : avgpeak;
                                    //var points = Math.Abs(maxidxinsignal - turn1);
                                    ////Console.WriteLine( s1/s2);
                                    ////如果最大值点与转折点1相差不到3个点的话就认为是毛刺
                                    //if (points < 5)
                                    //{
                                    //    if ((s1 > (avgpeak * threadtimes)) && s1>(s2* neartimes))
                                    //    {
                                    //        resultindex.Add(index[i]);
                                    //    }
                                    //}

                                }
                            }

                           

                        }

                    }

                }
            }
            catch (Exception ex)
            {
                string methodName = "";
                // 获取堆栈跟踪信息
                StackTrace stackTrace = new StackTrace(ex);
                // 获取第一个堆栈帧
                StackFrame? stackFrame = stackTrace.GetFrame(0);
                // 获取方法名
                if (stackFrame != null)
                {
                   
                    var s = stackFrame.GetMethod();
                    if (s != null)
                    {
                        methodName = s.Name;
                    }
                }
                LogErrorMessage.getErrormessage(methodName + "方法出现了错误：" + ex.StackTrace);
                Console.WriteLine(methodName + "方法出现了错误：" + ex.StackTrace);
            }


            return resultindex;
        }
        /// <summary>
        /// 获取指定列的SpikeinFileClass的数据，注意这只是1列的数据
        /// </summary>
        /// <param name="spikeindex"></param>
        /// <param name="spikecolumn"></param>
        /// <param name="filtervalue"></param>
        /// <returns></returns>
        public static List<SpikeinFileClass> GetspikeinFileClasses(List<List<int>> spikeindex,int spikecolumn,List<List<double>>filtervalue)
        {
            List<SpikeinFileClass> spikeinFileClasses = new List<SpikeinFileClass>();

            try
            {
                for (int i = 0; i < spikeindex.Count; i++)
                {
                    Console.WriteLine("GetspikeinFileClasses方法循环到"+i);
                    //选取spike序列里的第一个序号
                    var first = spikeindex[i].FirstOrDefault();
                    //选取spike序列里的最后一个序号
                    var last = spikeindex[i].LastOrDefault();
                    var firstfileindex = first / 2560;
                    var lastfileindex = last / 2560;
                    //判断商是否一致，如一致说明在一个文件里，不一致说明spike正好在两个文件里
                    if (firstfileindex == lastfileindex)
                    {
                        var s1 = new SpikeinFileClass();
                        s1.spikefileindex = firstfileindex;
                        s1.spikecollumn = spikecolumn;
                        s1.spikestartrow = first % 2560;//取余数就是开始的行号
                        s1.filtervalue = filtervalue[i];
                        spikeinFileClasses.Add(s1);
                    }
                    else
                    {
                        var s1 = new SpikeinFileClass();
                        s1.spikefileindex = firstfileindex;
                        s1.spikecollumn = spikecolumn;
                        s1.spikestartrow = first % 2560;//取余数就是开始的行号
                        var count = 2559 - s1.spikestartrow + 1;//表示前一个文件的需要更改的值的个数
                        s1.filtervalue=new List<double>();
                        List<double> values = new List<double>();
                        //帅选出前一个文件的需要更改的值
                        for (int j = 0; j < count; j++)
                        {
                            s1.filtervalue.Add(filtervalue[i][j]);
                        }
                        spikeinFileClasses.Add(s1);

                        values.Clear();//清零，重复使用
                        var s2 = new SpikeinFileClass();
                        s2.spikefileindex = lastfileindex;
                        s2.spikecollumn = spikecolumn;
                        s2.spikestartrow = 0;//后一个文件肯定是从第一行开始
                        s2.filtervalue = new List<double>();
                        for (int k = count; k < filtervalue[i].Count; k++)
                        {
                            s2.filtervalue.Add(filtervalue[i][k]);
                        }
                        spikeinFileClasses.Add(s2);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("GetspikeinFileClasses方法出现错误"+ex.Message);
                throw;
            }
          
            return spikeinFileClasses;
        }
    }



}
